package com.android.bonn.fast.net.interceptor.log;


import android.text.TextUtils;
import android.util.Log;

import java.io.IOException;
import java.util.List;

import okhttp3.Request;
import okio.Buffer;

class Logger {

    private static final int JSON_INDENT = 3;
    private static final String LINE_SEPARATOR = System.getProperty("line.separator");
    private static final String DOUBLE_SEPARATOR = LINE_SEPARATOR + LINE_SEPARATOR;
    private static final int MAX_LONG_SIZE = 100;
    private static final String N = "\n";
    private static final String T = "\t";

    protected Logger() {
        throw new UnsupportedOperationException();
    }

    private static boolean isEmpty(String line) {
        return TextUtils.isEmpty(line) || N.equals(line) || T.equals(line) || TextUtils.isEmpty(
                line.trim());
    }

    static void printJsonResponse(HttpLoggingInterceptor2.Builder builder, Request request,
                                  long chainMs, boolean isSuccessful, int code, String headers, String bodyString,
                                  List<String> segments) {
        String url = request.url().toString();
        String requestBodyValue = bodyToString(request);
        String requestBody = "║ requestBody:" + requestBodyValue;
        String responseBody = "║ responseBoby:" + bodyString;

        if (url.contains(".jpg") || url.contains(".png")) {
            responseBody = "║ responseBoby: is bitmap";
        }

        String tag = builder.getTag(false);
        Log.w("http", "╔══════ Log ═══════════════════════════════════════════════════════════════════════");
        Log.w("http", "║ Method: " + request.method());
        Log.w("http", "║ URL: " + request.url());
        if (!isEmpty(request.headers().toString())) {
            logLines(builder.getType(), tag, getRequest(request));
        }

        if (!TextUtils.isEmpty(requestBodyValue)) {
            Log.w("http", requestBody);
        }

        logLines(builder.getType(), tag, getResponse(headers, chainMs, code, isSuccessful, segments));

        printBody(responseBody);
        Log.w("http",
                "╚═══════════════════════════════════════════════════════════════════════════════════════");
    }

    private static String[] getRequest(Request request) {
        String message;
        String header = request.headers().toString();
        message =
                (isEmpty(header) ? "" : LINE_SEPARATOR + "Headers:" + LINE_SEPARATOR + dotHeaders(header));
        return message.split(LINE_SEPARATOR);
    }

    private static String[] getResponse(String header, long tookMs, int code, boolean isSuccessful,
                                        List<String> segments) {
        String message;
        message = (LINE_SEPARATOR
                + "is success : "
                + isSuccessful
                + " - "
                + "Received in: "
                + tookMs
                + "ms"
                + " - Status Code: "
                + code
                + (isEmpty(header) ? "" : "Headers:" + LINE_SEPARATOR + dotHeaders(header)));
        return message.split(LINE_SEPARATOR);
    }

    private static String slashSegments(List<String> segments) {
        StringBuilder segmentString = new StringBuilder();
        for (String segment : segments) {
            segmentString.append("/").append(segment);
        }
        return segmentString.toString();
    }

    private static String dotHeaders(String header) {
        String[] headers = header.split(LINE_SEPARATOR);
        StringBuilder builder = new StringBuilder();
        for (String item : headers) {
            builder.append("- ").append(item).append("\n");
        }
        return builder.toString();
    }

    private static void logLines(int type, String tag, String[] lines) {
        for (String line : lines) {
            int lineLength = line.length();
            for (int i = 0; i <= lineLength / MAX_LONG_SIZE; i++) {
                int start = i * MAX_LONG_SIZE;
                int end = (i + 1) * MAX_LONG_SIZE;
                end = end > line.length() ? line.length() : end;
                Log.w("http", "║ " + line.substring(start, end));
            }
        }

    }

    private static void printBody(String msg) {
        int max_str_length = 2001 - "http".length();
        //大于4000时
        while (msg.length() > max_str_length) {
            Log.w("http", msg.substring(0, max_str_length));
            msg = msg.substring(max_str_length);
        }
        //剩余部分
        Log.w("http", msg);
    }

    private static String bodyToString(final Request request) {
        try {
            final Request copy = request.newBuilder().build();
            final Buffer buffer = new Buffer();
            if (copy.body() == null) return "";
            copy.body().writeTo(buffer);
            return buffer.readUtf8();
        } catch (final IOException e) {
            return "{\"err\": \"" + e.getMessage() + "\"}";
        }
    }
}